package bai.publicwelfare_backend.interceptors;


import bai.publicwelfare_backend.common.utils.JwtUtil;
import bai.publicwelfare_backend.common.utils.Result;
import bai.publicwelfare_backend.exception.BusinessException;
import bai.publicwelfare_backend.exception.ErrorCode;
import bai.publicwelfare_backend.mapper.user.UserMapper;
import com.anji.captcha.util.StringUtils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;

@Component
@RequiredArgsConstructor
public class AuthInterceptor implements HandlerInterceptor {
    private static final Logger log = LogManager.getLogger(AuthInterceptor.class);

    private final JwtUtil jwtUtil;
    private final UserMapper userMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 放行登录和刷新令牌接口
        if (request.getRequestURI().startsWith("/auth/login") ||
                request.getRequestURI().equals("/auth/refresh")) {
            return true;
        }

        // 从请求头获取Token
        String token = request.getHeader("Authorization");
        if (StringUtils.isEmpty(token)) {
            throw new BusinessException(ErrorCode.TOKEN_MISSING, "Token缺失");
        }

        try {
            // 验证是否为访问令牌而非刷新令牌
            if (!jwtUtil.isAccessToken(token)) {
                throw new BusinessException(ErrorCode.TOKEN_TYPE_INVALID, "令牌类型不正确（请使用访问令牌）");
            }
            // 解码Token获取用户信息（尚未验证）
            DecodedJWT decodedJWT = JWT.decode(token);
            Long userId = decodedJWT.getClaim("userId").asLong();
            Integer tokenVersion = decodedJWT.getClaim("version").asInt();

            // 查询数据库验证用户及版本号
            Integer currentVersion = userMapper.getTokenVersionById(userId);
            if (currentVersion == null || currentVersion != tokenVersion) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户名不存在");
            }

            // 完整验证Token（签名+过期时间）
            if (!jwtUtil.validateToken(token, currentVersion)) {
                throw new BusinessException(ErrorCode.TOKEN_INVALID, "Token无效");
            }

            // 将用户ID存入请求上下文
            request.setAttribute("userId", userId);
            return true;

        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorCode(), e.getMessage());
        }
    }

    private boolean sendError(HttpServletResponse response, ErrorCode errorCode) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.setStatus(errorCode.getHttpStatus());

        Result<?> result = Result.error(
                Integer.valueOf(errorCode.getCode()),       // 使用String类型的错误码
                errorCode.getDefaultMsg()
        );

        response.getWriter().write(new ObjectMapper().writeValueAsString(result));
        return false;
    }

}
